
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ESP8266WebServer.h>
#include "PubSubClient.h"              
#include "ESP8266WiFiMulti.h"


ESP8266WiFiMulti WiFiMulti;//实例化ESP8266WiFiMulti对象
typedef struct
{
    String wifi;
    String sid;
    int num;
}WIFI_Info;
WIFI_Info wifi[10];
// const char* wifi = "";//wifi接入
// const char* sid  = "";

const char* ssid = "ziroom1604";//wifi接入
const char* password = "4001001111";
const char* ssid2 = "薇尔莉特";//wifi接入
const char* password2 = "HHeLiBeB";

const char* assid = "espAccessPoint";//创建AP热点
const char* asecret = "12345678";

String Wifi = "";
String sid = "";

#define ID_MQTT  "d7d5c79cdd4d428ca1453028d00c959f"     //用户私钥，控制台获取
const char*  topic = "light002";        //主题名字，可在巴法云控制台自行创建，名称随意
const char* mqtt_server = "bemfa.com"; //默认，MQTT服务器
const int mqtt_server_port = 9501;      //默认，MQTT服务器
WiFiClient espClient;
PubSubClient client(espClient);

ESP8266WebServer server(80);

const int ESP_BUILTIN_LED = 2;

int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000;

void MQTTreconnect() {
  int i=0;
  // Loop until we're reconnected
  if(!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(ID_MQTT)) {
      Serial.println("connected");
      Serial.print("subscribe:");
      Serial.println(topic);
      //订阅主题，如果需要订阅多个主题，可发送多条订阅指令client.subscribe(topic2);client.subscribe(topic3);
      client.subscribe(topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // if(i==10)
      //   break;
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void turnOnLed()
{
  digitalWrite(ESP_BUILTIN_LED,1);
}
void turnOffLed()
{
  digitalWrite(ESP_BUILTIN_LED,0);
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Topic:");
  Serial.println(topic);
  String msg = "";
  for (int i = 0; i < length; i++) {
    msg += (char)payload[i];
  }
  Serial.print("Msg:");
  Serial.println(msg);
  if (msg == "on") {//如果接收字符on，亮灯
    turnOnLed();//开灯函数
  } else if (msg == "off") {//如果接收字符off，亮灯
    turnOffLed();//关灯函数
  }
  msg = "";
}

void handleRoot() {       
  String html = "<!DOCTYPE html>                                                                    \
                 <html>                                                                             \
                 <body>                                                                             \
                 <h1>Submit wifi & sid</h1>                                                                 \
                                                                                                    \
                 <form action=\"/submit\" method=\'post\'>                                                \
                    <label for=\"fname\">wifi:</label>                                               \
                    <input type=\"text\" id=\"wifi\" name=\"wifi\"><br><br>                             \
                    <label for=\"lname\">sid:</label>                                               \
                    <input type=\"text\" id=\"sid\" name=\"sid\"><br><br>                                 \
                    <input type=\"submit\" value=\"Submit\">                                              \
                 </form>                                                                            \
                 </body>                                                                            \
                 </html>" ;                                                                                

  server.send(200, "text/html", html);
}

void ADD_WIFI_AP()
{
  int num=0;
  for(num=0;num<wifi[0].num;num++)
  {
    if(wifi[num+1].wifi!=NULL && wifi[num+1].sid!=NULL)
      WiFiMulti.addAP((wifi[num+1].wifi).c_str(), (wifi[num+1].sid).c_str());  
  }
}
void ConnetToWifi()
{
  int timeout=0;
  ADD_WIFI_AP();
  while (WiFiMulti.run() != WL_CONNECTED)
  {
    delay(500);
    Serial.println("connect...");
    if(timeout==10)
    {
      timeout=0;
      break;
    }
    timeout++;
   // ESP.restart();
  }
}
void ReConnetToWifi()
{
  int timeout=0;
  int i;
  i=wifi[0].num;
  WiFiMulti.addAP((wifi[i].wifi).c_str(), (wifi[i].sid).c_str());  
  while (WiFiMulti.run() != WL_CONNECTED)
  {
    delay(500);
    Serial.println("reconnect...");
    if(timeout==10)
    {
      timeout=0;
      break;
    }
    timeout++;
  }
}

void Print_WIFI()
{
  int i=0;
  for(i=0;i<=wifi[0].num;i++)
  {
    Serial.println(wifi[i].wifi);
    Serial.println(wifi[i].sid);
    Serial.println(wifi[i].num);
  }
}

void handleLED() {          
  int i=0;                
  if (server.hasArg("wifi") && server.hasArg("sid")) {
    i=++wifi[0].num;
    Wifi = server.arg("wifi");
    sid = server.arg("sid");
    server.send(200, "text/plain", "Received: " + Wifi + sid);
    wifi[i].wifi=Wifi;
    wifi[i].sid=sid;
    wifi[i].num=i;
    Print_WIFI();
    ReConnetToWifi();
    MQTTreconnect();
  }
   else {
    server.send(400, "text/plain", "Bad Request");
  }
}


void WIFI_Info_Init()
{
  int i=0;
  for(i=0;i<10;i++)
  {
    wifi[i].wifi=NULL;
    wifi[i].sid =NULL;
    wifi[i].num =0;
  }
}

void setup() {
  Serial.begin(9600);
  WiFi.mode(WIFI_AP_STA);
  WiFi.softAP(assid, asecret);  
  server.on("/", handleRoot);
  server.on("/submit", HTTP_POST, handleLED); 
  WIFI_Info_Init();
  ConnetToWifi();
  client.setServer(mqtt_server, mqtt_server_port);//设置mqtt服务器
  client.setCallback(callback); //mqtt消息处理

  Serial.println(WiFi.softAPIP()); 
  Serial.println("1...");
  server.begin();//启动tcp连接 
  Serial.println("2...");
  pinMode(ESP_BUILTIN_LED, OUTPUT);
}

void loop() {
  client.loop();
  server.handleClient();
  if (!client.connected()) {
    MQTTreconnect();
  }

}

